// 环形图片
import { useEffect, useRef } from 'react'
import * as THREE from 'three'
import './App.css'

// 导入GLTFLoader用于加载GLB模型
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
import Stats from 'three/examples/jsm/libs/stats.module.js';
function App() {
  const containerRef = useRef(null)
  const scrollContainerRef = useRef(null) // 滚动容器的引用

  useEffect(() => {
    const stats = new Stats();
    document.body.appendChild(stats.dom);
    // 场景
    const scene = new THREE.Scene()
    // 创建相机
    const camera = new THREE.PerspectiveCamera(
      75, // 增加视野角度，更适合第一人称
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    )

    // 设置相机初始位置
    camera.position.set(0, 1.6, 5); // 模拟人眼高度

    // 创建渲染器时设置为全屏
    const renderer = new THREE.WebGLRenderer({
      antialias: true, // 抗锯齿
      alpha: true // 支持透明背景
    })
    renderer.setSize(window.innerWidth, window.innerHeight)
    renderer.setPixelRatio(window.devicePixelRatio) // 支持高DPI屏幕
    renderer.shadowMap.enabled = true; // 启用阴影
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;

    // 创建 PointerLockControls
    const controls = new PointerLockControls(camera, renderer.domElement);

    // 添加指针锁定事件监听器
    const onPointerLockChange = () => {
      if (document.pointerLockElement === renderer.domElement) {
        console.log('指针已锁定');
      } else {
        console.log('指针已解锁');
      }
    };

    const onPointerLockError = () => {
      console.error('指针锁定失败');
    };

    document.addEventListener('pointerlockchange', onPointerLockChange);
    document.addEventListener('pointerlockerror', onPointerLockError);

    // 点击canvas锁定指针
    const onCanvasClick = () => {
      controls.lock();
    };

    renderer.domElement.addEventListener('click', onCanvasClick);

    // 将渲染器添加到容器
    if (containerRef.current) {
      containerRef.current.appendChild(renderer.domElement)
    }

    // 键盘事件
    const move = { forward: false, backward: false, left: false, right: false, up: false, down: false };
    const velocity = new THREE.Vector3();
    const direction = new THREE.Vector3();
    const moveSpeed = 20.0; // 调整移动速度

    const onKeyDown = (e) => {
      switch (e.code) {
        case 'KeyW': move.forward = true; break;
        case 'KeyS': move.backward = true; break;
        case 'KeyA': move.left = true; break;
        case 'KeyD': move.right = true; break;
        case 'Space': move.up = true; e.preventDefault(); break;
        case 'ShiftLeft': move.down = true; break;
        case 'Escape': controls.unlock(); break; // ESC键解锁指针
      }
    };

    const onKeyUp = (e) => {
      switch (e.code) {
        case 'KeyW': move.forward = false; break;
        case 'KeyS': move.backward = false; break;
        case 'KeyA': move.left = false; break;
        case 'KeyD': move.right = false; break;
        case 'Space': move.up = false; break;
        case 'ShiftLeft': move.down = false; break;
      }
    };

    document.addEventListener('keydown', onKeyDown);
    document.addEventListener('keyup', onKeyUp);

    // 创建一个场景图
    const baseObrit = new THREE.Object3D()
    baseObrit.position.set(0, 0, 0)
    scene.add(baseObrit)

    // 创建模型场景图
    const modelObrit = new THREE.Object3D()
    modelObrit.position.set(0, 0, 0)
    scene.add(modelObrit)

    function addStar() {
      const geometry = new THREE.SphereGeometry(0.25, 24, 24);
      const material = new THREE.MeshBasicMaterial({ color: 0xfbc017 });

      const star = new THREE.Mesh(geometry, material);

      const [x, y, z] = Array(3)
        .fill()
        .map(() => THREE.MathUtils.randFloatSpread(100));

      star.position.set(x, y, z);
      baseObrit.add(star);
    }

    Array(200).fill().forEach(addStar);

    // GLB模型加载相关
    const gltfLoader = new GLTFLoader();
    let loadedModel = null;
    gltfLoader.load(
      '/glbExample/quit.glb',
      (gltf) => {
        console.log('GLB模型加载成功:', gltf);
        loadedModel = gltf.scene;
        loadedModel.position.set(0, 0, 0);

        loadedModel.traverse((child) => {
          if (child.isMesh) {
            child.castShadow = true;
            child.receiveShadow = true;
            // 如果是MeshStandardMaterial，调整粗糙度
            if (child.material.type === 'MeshStandardMaterial') {
              child.material.roughness = 0.8; // 增加粗糙度
              child.material.metalness = 0.1; // 降低金属度
            }

            child.material.needsUpdate = true;
          }
        });

        modelObrit.add(loadedModel);
      },
      (progress) => {
        const percentComplete = (progress.loaded / progress.total) * 100;
        console.log(`GLB模型加载进度: ${percentComplete.toFixed(2)}%`);
      },
      (error) => {
        console.error('GLB模型加载失败:', error);
      }
    );

    // 图片相关
    const loader = new THREE.TextureLoader();
    const imageCount = 12;
    const radius = 10;
    const group = new THREE.Group();

    const maxSize = 3;
    for (let i = 0; i < imageCount; i++) {
      const imgPath = `/images/${i + 1}.jpg`;

      loader.load(imgPath, (texture) => {
        texture.wrapS = THREE.RepeatWrapping;
        texture.repeat.x = -1;

        const image = texture.image;
        const imageWidth = image.width;
        const imageHeight = image.height;
        const aspectRatio = imageWidth / imageHeight;

        let planeWidth, planeHeight;
        if (aspectRatio > 1) {
          planeWidth = maxSize;
          planeHeight = maxSize / aspectRatio;
        } else {
          planeHeight = maxSize;
          planeWidth = maxSize * aspectRatio;
        }

        const material = new THREE.MeshBasicMaterial({
          map: texture,
          side: THREE.DoubleSide,
          transparent: true,
          alphaTest: 0.1
        });

        const plane = new THREE.Mesh(new THREE.PlaneGeometry(planeWidth, planeHeight), material);
        const angle = (i / imageCount) * Math.PI * 2;
        plane.position.set(Math.cos(angle) * radius, 0, Math.sin(angle) * radius);
        plane.lookAt(0, 0, 0);
        group.add(plane);
      });
    }

    group.position.set(0, 2, 0);
    baseObrit.add(group)

    scene.background = new THREE.Color(0x000)

    // 添加地面
    const planeSize = 40;
    loader.load('./checker.png', (texture) => {
      texture.wrapS = THREE.RepeatWrapping;
      texture.wrapT = THREE.RepeatWrapping;
      texture.magFilter = THREE.NearestFilter;
      texture.colorSpace = THREE.SRGBColorSpace;
      const repeats = planeSize / 2;
      texture.repeat.set(repeats, repeats);
      const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);
      const planeMat = new THREE.MeshPhongMaterial({
        map: texture,
        side: THREE.DoubleSide,
      });
      const mesh = new THREE.Mesh(planeGeo, planeMat);
      mesh.rotation.x = Math.PI * -.5;
      mesh.receiveShadow = true;
      scene.add(mesh);
    });

    // 光源相关
    const color = 0xFFFFFF;
    const intensity = 133;
    const light = new THREE.PointLight(color, intensity);
    light.position.set(0, 10, 0);
    light.castShadow = true;
    light.shadow.mapSize.width = 2048;
    light.shadow.mapSize.height = 2048;
    scene.add(light);

    // 增加环境光强度，减少对点光源的依赖
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.8); // 提高环境光
    scene.add(ambientLight);

    // 滚动事件处理函数

    // 窗口大小变化处理函数
    const handleResize = () => {
      camera.aspect = window.innerWidth / window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
      renderer.setPixelRatio(window.devicePixelRatio)
    }

    window.addEventListener('resize', handleResize);

    // 渲染循环
    let prevTime = performance.now();

    function animate() {
      requestAnimationFrame(animate)

      const time = performance.now();
      const delta = (time - prevTime) / 1000;

      // 只有在指针锁定时才处理移动
      if (controls.isLocked) {
        // 应用阻尼
        velocity.x -= velocity.x * 10.0 * delta;
        velocity.z -= velocity.z * 10.0 * delta;
        velocity.y -= velocity.y * 10.0 * delta;

        direction.z = Number(move.forward) - Number(move.backward);
        direction.x = Number(move.right) - Number(move.left);
        direction.y = Number(move.up) - Number(move.down);
        direction.normalize();

        if (move.forward || move.backward) velocity.z -= direction.z * moveSpeed * delta;
        if (move.left || move.right) velocity.x -= direction.x * moveSpeed * delta;
        if (move.up || move.down) velocity.y += direction.y * moveSpeed * delta;

        controls.moveRight(-velocity.x * delta);
        controls.moveForward(-velocity.z * delta);

        // 垂直移动
        camera.position.y += velocity.y * delta;

        // 限制相机高度
        camera.position.y = Math.max(0.5, Math.min(camera.position.y, 20));
      }



      // 旋转模型
      modelObrit.rotation.y -= 0.005;

      prevTime = time;
      stats.update(); // 每帧更新
      // 渲染场景
      renderer.render(scene, camera)
    }

    animate()

    // 清理函数
    return () => {
      // 移除事件监听器
      document.removeEventListener('pointerlockchange', onPointerLockChange);
      document.removeEventListener('pointerlockerror', onPointerLockError);
      document.removeEventListener('keydown', onKeyDown);
      document.removeEventListener('keyup', onKeyUp);
      renderer.domElement.removeEventListener('click', onCanvasClick);

      if (scrollContainerRef.current) {
        scrollContainerRef.current.removeEventListener('scroll', handleScroll);
      }
      window.removeEventListener('resize', handleResize);

      // 清理Three.js资源
      renderer.dispose();

      // 移除DOM元素
      if (containerRef.current && renderer.domElement) {
        containerRef.current.removeChild(renderer.domElement)
      }
    }
  }, [])

  return (
    <div
      ref={scrollContainerRef}
      className='container w-full h-[100vh] overflow-auto hide-scrollbar'
      style={{
        overflowY: 'auto',
        height: '100vh'
      }}
    >
      <div
        ref={containerRef}
        style={{
          position: 'fixed',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          zIndex: 1, // 改为正值，确保可以接收事件
          // 移除 pointerEvents: 'none' 以允许鼠标交互
        }}
      />

      {/* 添加使用说明 */}
      <div style={{
        position: 'fixed',
        top: 20,
        right: 20,
        color: 'white',
        backgroundColor: 'rgba(0,0,0,0.7)',
        padding: '10px',
        borderRadius: '5px',
        fontSize: '14px',
        zIndex: 1000,
        pointerEvents: 'none'
      }}>
        <div>点击画面锁定鼠标控制视角</div>
        <div>WASD: 移动 | 空格: 上升 | Shift: 下降</div>
        <div>ESC: 解锁鼠标</div>
      </div>
    </div>
  )
}

export default App
